snippet def "defines a new function with a multiline block" !b
def ${1:name}(${2:params}) do
	$3
end
endsnippet

snippet defl "defines a new function" !b
def ${1:name}(${2:params}), do: $3
endsnippet

snippet defp "defines a private method with a multiline block" !b
defp ${1:name}(${2:params}) do
	$3
end
endsnippet

snippet defpl "defines a new private function" !b
defp ${1:name}(${2:params}), do: $3
endsnippet

snippet defmod "defines a new module" !b
defmodule ${1:name} do
	$3
end
endsnippet

snippet defi "defines a new implementation" b
defimpl ${1:name}, for: $2 do
	$3
end
endsnippet

snippet defc "defines a callback" b
defcallback ${1:name} :: $2
endsnippet

snippet defpro "defines a new protocol" b
defprotocol ${1:name} do
	$2
end
endsnippet

snippet ht "inserts a [head | tail]" !i
[head | tail]
endsnippet

snippet test "add a test case" !b
test "${1:description}"${2:, context} do
	$3
end
endsnippet

snippet server "incorporate the GenServer behaviour" !b
use GenServer.Behaviour
endsnippet

snippet fsm "incorporate the GenFSM behaviour" !b
use GenFSM.Behaviour
endsnippet

snippet if "add an if block" !b
if ${1:condition} do
	$2
end
endsnippet

snippet ife "add an if-else block" !b
if ${1:condition} do
	$2
else
	$3
end
endsnippet

snippet doc "define function documentation with example" b
@doc """
$1. Example:

		iex> $2
		$3

"""
endsnippet
snippet mdoc "define module document" i
@moduledoc """
$1

"""
endsnippet

snippet ex "add example" i
Example:

		iex> $1
		$2

endsnippet

snippet defsup "define a supervisor module" b
defmodule ${1:name} do
	@moduledoc """
	$2
	"""
	use Supervisor

	def start_link do
		:supervisor.start_link __MODULE__, []
	end

	def init(${3:params}) do
	child_processes = [
		worker($4, $3)
	]
	supervise child_processes, strategy: :$5
	end
end
endsnippet

snippet defgen "define a GenServer module" b
defmodule ${1:name} do
	@moduledoc """
	$2
	"""
	use GenServer

	### Public API

	def start_link do
		{:ok, server} = :gen_server.start_link __MODULE__, ${3:[]}, ${4:[]}
	end

	### GenServer API
	def init(${5:state}) do
		{:ok, $5}
	end

	def handle_call(, _from, state) do
		
	end

	def handle_cast(, state) do
		
	end
end
endsnippet

snippet deftest "define a test module" b
defmodule ${1:name} do
	use ExUnit.Case

	test "$2" do
		$3
	end

	$4
end
endsnippet

snippet defst "define a new structure" b
defmodule ${1:name} do
	defstruct $2: ${3:nil},
						$4: ${5:nil}
end
endsnippet

snippet quo "define a quote" b
quote do
	$1
end
endsnippet

snippet ben "define a new benchmark test" b
bench "${1:name}" do
	$2
end
endsnippet

snippet defben "define a bench module" b
defmodule ${1:name} do
	use Benchfella

	bench "${2:bname}" do
		$3
	end
end
endsnippet

snippet task "define a new mix task" b
defmodule Mix.Tasks.${1:Name} do
	use Mix.Task

	@shortdoc "$2"

	@moduledoc """
	$3
	"""

	def run(args) do
		{opts, args, _} = OptionParser.parse(args, strict: [dev: :boolean])
		run(args, opts)
	end

	def run(args, opts) do
		$4
	end
end
endsnippet
